#pragma	once

//	Inline static mathematics for common use

namespace	MomogenkyouHelper	{

extern	const	float2		FLOAT2_ZERO;
extern	const	float2		FLOAT2_ONE;
extern	const	float2		FLOAT2_UNIT_X;
extern	const	float2		FLOAT2_UNIT_Y;

extern	const	float3		FLOAT3_ZERO;
extern	const	float3		FLOAT3_ONE;
extern	const	float3		FLOAT3_UNIT_X;
extern	const	float3		FLOAT3_UNIT_Y;
extern	const	float3		FLOAT3_UNIT_Z;

extern	const	float4		FLOAT4_ZERO;
extern	const	float4		FLOAT4_ONE;
extern	const	float4		FLOAT4_UNIT_X;
extern	const	float4		FLOAT4_UNIT_Y;
extern	const	float4		FLOAT4_UNIT_Z;

extern	const	MATRIX		MATRIX_IDENTITY;


__inline	float	Clamp(const float & Min, const float & Max, const float & Value)
{
	return (Value > Max)? Max : (Value < Min)? Min : Value;
}

__inline	void	Clamp(const float & Min, const float & Max, const float & Value, float & outValue)
{
	outValue = (Value > Max)? Max : (Value < Min)? Min : Value;
}

__inline	float	Lerp(const float & v1, const float & v2, const float Amount)
{
	return	(v2 - v1)  * Amount + v1;
}

__inline	void	Lerp(const float & v1, const float & v2, const float Amount, float & outValue)
{
	outValue = (v2 - v1)  * Amount + v1;
}

__inline	float	WarpAngle(float Angle)
{
	if(Angle > PI2)	Angle -= PI2;
	if(Angle < 0)	Angle += PI2;
	return	Angle;
}

__inline	void	WarpAngle(const float & Angle, float & outValue)
{
	outValue = Angle;
	if(outValue > PI2)	outValue -= PI2;
	if(outValue < 0)	outValue += PI2;
}

__inline	float	DirectionToAngle(const float & x, const float & y)
{
	return atan2f(x, y);
}

__inline	void	DirectionToAngle(const float & x, const float & y, float & outValue)
{
	outValue = atan2f(x, y);
}

__inline	float	DirectionToAngle_v2(const float2 * vDirection)
{
	return atan2f(vDirection->x, vDirection->y);
}

__inline	void	DirectionToAngle_v2(const float2 * vDirection, float & outValue)
{
	outValue = atan2f(vDirection->x, vDirection->y);
}

__inline	float	DirectionToAngle_v3xy(const float2 * vDirection)
{
	return atan2f(vDirection->x, vDirection->y);
}

__inline	void	DirectionToAngle_v3xy(const float2 * vDirection, float & outValue)
{
	outValue = atan2f(vDirection->x, vDirection->y);
}

__inline	float	DirectionToAngle_v3_xz(const float3 * vDirection)
{
	return atan2f(vDirection->x, vDirection->z);
}

__inline	void	DirectionToAngle_v3_xz(const float3 * vDirection, float & outValue)
{
	outValue = atan2f(vDirection->x, vDirection->z);
}

__inline	float	DirectionToAngle_PI2(const float & x, const float & y, const float & rx, const float & ry)
{
	return atan2f(x, y) - atan2f(rx, ry);
}

__inline	void	DirectionToAngle_PI2(const float & x, const float & y, const float & rx, const float & ry, float & outValue)
{
	outValue = atan2f(x, y) - atan2f(rx, ry);
}

}